package test

import (
	"blog/utils"
	"encoding/json"
	"fmt"
	"github.com/olivere/elastic/v7"
)

// Person 数据结构体
type Person struct {
	Name string `json:"name"`
	Age  int    `json:"age"`
	Like string `json:"like"`
	ID   string `json:"id"`
}

const tableName = "users"

func EsTest() {
	randUsers()
	//showList()
	//hello()
	//delAll()
	//addOne()

	//kk := Person{
	//	Name: utils.GetRandChineseName(),
	//	Age:  utils.GetRandNum(10, 100),
	//	Like: utils.GetRandName(5, true),
	//}
	//
	//kks, _ := json.Marshal(kk)
	//fmt.Println(string(kks))
	//
	//AddJson(string(kks))

	//p := ShowPersonByID("dHgWypAByiNL0kF1PO2q")
	//fmt.Println(p.Name, p.Like)

	// 添加数据

}

// ------------------------ 临时代码调试 ----------------------

/*
描述：高中学科网绝密资料是专为高中生提供的内部特供学习资料，涵盖了高中九大学科的核心知识点。包含试题、试卷、课件、教案等超1200万套教学资源，满足学生全方位学习需求。
链接：https://pan.quark.cn/s/18e3c5d25a0a

需要读取很多的题库然后进行分类整理
*/

// RandUsers 随机添加用户信息 -- ok 成功
func randUsers() {
	for i := 0; i < 10; i++ {
		age := utils.GetRandNum(10, 100)
		AddPersonWithoutId(Person{
			Name: utils.GetRandChineseName(),
			Age:  age,
			Like: utils.GetRandName(5, true),
		})
	}
}

func hello() {
	SearchByName("name:孔")
}

func showList() {
	res := ShowPersonList()
	for _, item := range res {
		fmt.Println(item.Name)
		fmt.Println(item.ID)
	}
}

func delAll() {
	res := ShowPersonList()
	for _, item := range res {
		//fmt.Println(item.Name)
		//fmt.Println(item.ID)
		fmt.Println("删除", item.Name)
		DeltePerson(item.ID)
	}
}

func addOne() {
	// 添加单个数据,查询单个数据
	AddPersonWithID(Person{
		Name: "张三",
		Age:  13,
		Like: "法外狂徒",
	}, "1")
	// 根据ID索引查询数据
	ShowPersonByID("1")

	//fmt.Println("------ 修改数据 -----------")
	//
	//UpdatePerson("1")
	//fmt.Println("------ 修改数据后 -----------")
	//ShowPersonByID("1")

	AddPersonWithoutId(Person{
		Name: "韩云",
		Age:  300,
		Like: "休闲",
	})
}

// ------------------------ 调用方法 ----------------------

// AddPersonWithID 添加单个数据,指定ID索引 -- ok
func AddPersonWithID(user Person, pId string) {
	// 这里虽然传的是ID,但是和常规MySQL的int类型ID是不一样的
	res, err := utils.ElasticClient.Index().Index(tableName).Id(pId).BodyJson(user).Do(utils.DoCtxBackground)
	if err != nil {
		fmt.Println("插入es数据错误", err)
	}
	fmt.Printf("插入es成功:ID= %s --- index= %s \n", res.Id, res.Index)
}

// AddPersonWithoutId 插入单个数据不带ID,会生成随机的ID -- ok
func AddPersonWithoutId(user Person) {
	res, err := utils.ElasticClient.Index().Index(tableName).BodyJson(user).Do(utils.DoCtxBackground)
	if err != nil {
		fmt.Println("插入es数据错误", err)
	}
	fmt.Printf("插入es成功:ID= %s --- index= %s \n", res.Id, res.Index)
}

// ShowPersonByID ShowPersonList 显示es数据通过ID
func ShowPersonByID(pId string) Person {
	var user Person
	res, err := utils.ElasticClient.Get().Index(tableName).Id(pId).Do(utils.DoCtxBackground)
	if err != nil {
		fmt.Println("查询es数据错误", err)
		return user
	}
	if res.Found {
		fmt.Printf("接收成功 %s \n", res.Id)
		err = json.Unmarshal(res.Source, &user)
	}
	return user
}

// UpdatePerson 修改数据
func UpdatePerson(pId string) bool {
	res, err := utils.ElasticClient.Update().Index(tableName).Id(pId).Doc(map[string]interface{}{"name": "王五"}).Do(utils.DoCtxBackground)
	if err != nil {
		fmt.Println("修改数据es数据错误", err)
		return false
	}
	fmt.Println("ok", res.Id)
	return true
}

// DeltePerson 删除一条数据
func DeltePerson(pId string) {
	res, err := utils.ElasticClient.Delete().Index(tableName).Id(pId).Do(utils.DoCtxBackground)
	if err != nil {
		fmt.Println("删除数据es数据错误", err)
	}
	fmt.Println("ok", res.Id)
}

// ShowPersonList 显示数据列表
func ShowPersonList() []Person {
	res, err := utils.ElasticClient.Search().Index(tableName).Do(utils.DoCtxBackground)
	if err != nil {
		fmt.Println("查询es数据错误", err)
	}
	num := res.Hits.TotalHits.Value
	if num > 0 {
		var users []Person
		for _, item := range res.Hits.Hits {
			var user Person
			fmt.Println(item.Id)
			fmt.Println(string(item.Source))
			err = json.Unmarshal(item.Source, &user)
			user.ID = item.Id
			if err != nil {
				fmt.Println("解析数据失败", err)
				continue
			}
			users = append(users, user)
		}
		return users
	}
	return nil
}

// SearchByName 条件查询
func SearchByName(name string) {
	q := elastic.NewQueryStringQuery(name)
	rsp, err := utils.ElasticClient.Search(tableName).Query(q).Do(utils.DoCtxBackground)
	if err != nil {
		fmt.Println("查询失败")
	}
	fmt.Println(rsp)
	num := rsp.Hits.TotalHits.Value
	fmt.Println("搜索结果记录数量", num)
	if num > 0 {
		for _, item := range rsp.Hits.Hits {
			var p Person
			err = json.Unmarshal(item.Source, &p)
			if err != nil {
				fmt.Println("格式化失败", err)
			}
			fmt.Println(p.Name, item.Id)
		}
	}
}

// 多条件查询
